/// <reference path="../model/BlockPoint.ts" />
/// <reference path="./Matrix.ts" />

namespace tetris {
    const ERASE_INTERVAL = 25;

    export interface IEraserOptions {
        matrix: Matrix;
        render: Function;
        interval?: number;
    }

    export class Eraser {
        private _fulls: Array<number>;
        private readonly _options: IEraserOptions;

        constructor(options: IEraserOptions) {
            this._options = options;
            if (!options.interval) {
                options.interval = ERASE_INTERVAL;
            }
        }

        private get matrix(): Matrix {
            return this._options.matrix;
        }

        private get width(): number {
            return this._options.matrix.width;
        }

        get rowsCount(): number {
            return (this._fulls && this._fulls.length) || 0;
        }

        check(): boolean {
            const fulls = this._fulls = this.matrix.getFullRows();
            return !!fulls.length;
        }

        async erase(): Promise<MatrixData> {
            const matrix = this.matrix;
            const width = matrix.width;
            const fulls = this._fulls;
            const render = this._options.render;

            return new Promise((resolve: (value?: any) => void) => {
                let x: number = 0;
                const t = setInterval(() => {
                    fulls.forEach((y: number) => {
                        matrix.set(x, y);
                        render();
                    });

                    if (++x >= width) {
                        clearInterval(t);
                        this.matrix.removeRows(this._fulls);
                        resolve();
                    }
                }, this._options.interval);
            });
        }
    }
}